package com.mrd.gtimp.base.service;

import com.mrd.constant.SystemSettings;
import com.mrd.exception.QueryException;
import com.mrd.gtimp.base.entity.Process;
import com.mrd.gtimp.base.entity.SysMsgSetting;
import com.mrd.gtimp.base.entity.SysMsgTemplate;
import com.mrd.gtimp.base.repository.ProcessDao;
import com.mrd.gtimp.base.repository.SysMsgSettingDao;
import com.mrd.gtimp.base.repository.SysMsgTemplateDao;
import com.mrd.gtimp.base.service.itf.SysMsgSendBiz;

import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * <p> application name: sample <p> copyright: Copyright@2012 明睿达科技有限公司
 */

/**
 * @author winaya
 */
public abstract class MsgSendAbstract implements SysMsgSendBiz {

    private static final Logger logger = Logger.getLogger(MsgSendAbstract.class);

    /**
     * 业务节点
     */
    protected Process process;
    /**
     * 模板
     */
    protected SysMsgTemplate template;
    /**
     * 供应商消息设置
     */
    protected SysMsgSetting supSetting;
    /**
     * 客户消息设置
     */
    protected SysMsgSetting cusSetting;

    /**
     * 节点dao 需要注入
     */
    protected ProcessDao processDao;

    /**
     * 消息数据管理dao 需要注入
     */
    protected SysMsgBiz sysMsgBiz;
    /**
     * 信息模板dao 需要注入
     */
    protected SysMsgTemplateDao sysMsgTemplateDao;
    /**
     * 信息设置dao 需要注入
     */
    protected SysMsgSettingDao sysMsgSettingDao;

    /**
     * 初始化，模板和业务节点
     */
    protected boolean findToInit(String processId, String supCompanyId, String cusCompanyId) {
        if (SystemSettings.PROCESSES == null) {
            try {
                SystemSettings.PROCESSES = processDao.findAllEntity();
            } catch (QueryException e) {
                e.printStackTrace();
                return false;
            }
        }
        // 初始化全局变量
        if (SystemSettings.SYSTEM_MSG_SETTINGS == null) {
            try {
                List<SysMsgSetting> settings = sysMsgSettingDao.findAllEntity();
                Map<String, List<SysMsgSetting>> settingMap = new HashMap<String, List<SysMsgSetting>>();
                for (SysMsgSetting sysMsgSetting : settings) {
                    String companyId = sysMsgSetting.getCompany().getId();
                    List<SysMsgSetting> list = settingMap.get(companyId);
                    if (list == null) {
                        list = new ArrayList<SysMsgSetting>();
                        settingMap.put(companyId, list);
                    }
                    list.add(sysMsgSetting);
                }
                SystemSettings.SYSTEM_MSG_SETTINGS = settingMap;
            } catch (Exception e) {
                e.printStackTrace();
                return false;
            }
        }
        // 初始化全局变量
        if (SystemSettings.SYSTEM_MSG_TEMPALTES == null) {
            try {
                List<SysMsgTemplate> templates = sysMsgTemplateDao.findAllEntity();
                Map<String, List<SysMsgTemplate>> templateMap = new HashMap<String, List<SysMsgTemplate>>();
                for (SysMsgTemplate sysMsgTemplate : templates) {
                    String companyId = sysMsgTemplate.getCompany() == null ? null : sysMsgTemplate
                            .getCompany().getId();
                    List<SysMsgTemplate> list = templateMap.get(companyId);
                    if (list == null) {
                        list = new ArrayList<SysMsgTemplate>();
                        templateMap.put(companyId, list);
                    }
                    list.add(sysMsgTemplate);
                }
                SystemSettings.SYSTEM_MSG_TEMPALTES = templateMap;
            } catch (Exception e) {
                e.printStackTrace();
                return false;
            }
        }

        // 初始化process
        List<Process> processes = SystemSettings.PROCESSES;
        for (Process process : processes) {
            if (process.getProcessId().equals(processId)) {
                this.process = process;
                break;
            }
        }
        if (process == null) {
            logger.info("未找到该节点!节点id为:" + processId);
            return false;
        } else if ("1".equals(process.getProcessState())) {
            logger.info("该节点已被禁用!节点id为:" + processId);
            return false;
        }
        // 初始化消息设置
        supSetting = getSetting(process, supCompanyId);
        cusSetting = getSetting(process, cusCompanyId);
        // 初始化模板
        List<SysMsgTemplate> templates = SystemSettings.SYSTEM_MSG_TEMPALTES.get(supCompanyId);
        if (templates != null) {
            for (SysMsgTemplate sysMsgTemplate : templates) {
                if (process.getProcessId().equals(sysMsgTemplate.getProcess().getProcessId())
                        && StringUtils.isNotEmpty(sysMsgTemplate.getContent())) {
                    template = sysMsgTemplate;
                    break;
                }
            }
        }
        if (template == null) {
            templates = SystemSettings.SYSTEM_MSG_TEMPALTES.get(null);
            for (SysMsgTemplate sysMsgTemplate : templates) {
                if (process.getProcessId().equals(sysMsgTemplate.getProcess().getProcessId())
                        && StringUtils.isNotEmpty(sysMsgTemplate.getContent())) {
                    template = sysMsgTemplate;
                    break;
                }
            }
        }
        if (template == null) {
            logger.info("未找到该节点的模板设置或模板设置为空并且公用模板未设置!节点id为:" + processId + "公司id为:" + supCompanyId);
            return false;
        }
        return true;
    }

    /**
     * 检查供应商发送消息设置，供应商默认发送消息，并保存记录
     */
    protected boolean checkSupSetting() {
        if (supSetting == null) {
            return true;
        } else if ("0".equals(supSetting.getUseState())) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 检查客户接受消息设置，客户默认不接收消息，并保存记录
     */
    protected boolean checkCusSetting() {
        if (supSetting == null) {
            return false;
        } else if ("0".equals(supSetting.getUseState())) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 组装消息
     */
    private String setMsg(SysMsgTemplate template, String... args) {
        String content = template.getContent();
        String regex = "\\{\\d+ *\\}";// 匹配{1},{2 }等表达式
        Pattern pattern = Pattern.compile(regex);
        Matcher match = pattern.matcher(content);
        while (match.find()) {
            String group = match.group();
            String replaceStr = "";
            try {
                int argIndex = Integer.parseInt(group.substring(1, group.length() - 1).trim());
                replaceStr = args[argIndex - 1];
            } catch (Exception e) {
                match.start();
                continue;// 参数无法解析成数字或者无法取得参数值则下一次匹配
            }
            content = match.replaceFirst(replaceStr);
            match.reset(content);
        }
        return content;
    }

    /**
     * 发送消息
     */
    protected abstract boolean send(String content);

    /**
     * 保存消息发送情况
     */
    protected abstract boolean saveMsgHistory(String processId, String supCompanyId,
                                              String cusCompanyId, String content, String bizId, boolean supSendState,
                                              boolean cusSendState) throws Exception;

    /**
     * 发送消息流程
     */

    public void updateToSendMsg(String processId, String supCompanyId, String cusCompanyId,
                                String bizId, String... args) {
        boolean initState = findToInit(processId, supCompanyId, cusCompanyId);
        if (!initState) {
            return;
        }
        String content = setMsg(template, args);// 组装需要发送的消息
        boolean supSendState = checkSupSetting();// 供应商发送设置检测
        boolean cusSendState = checkCusSetting();// 客户发送设置检查
        try {
            saveMsgHistory(processId, supCompanyId, cusCompanyId, content, bizId, supSendState, cusSendState);
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (!supSendState) {
            return;
        }
        if (!cusSendState) {
            return;
        }
        send(content);// 发送消息
    }

    private SysMsgSetting getSetting(Process process, String companyId) {
        List<SysMsgSetting> settings = SystemSettings.SYSTEM_MSG_SETTINGS.get(companyId);
        if (settings != null && settings.size() != 0) {
            for (SysMsgSetting sms : settings) {
                if (sms.getProcess().getProcessId().equals(process.getProcessId())) {
                    return sms;
                }
            }
        }
        return null;
    }

    /**
     * 注入ProcessDao和biz中dao注入方法一直
     */
    public abstract void setProcessDao(ProcessDao processDao);

    /**
     * 注入SysMsgTemplateDao和biz中dao注入方法一直
     */
    public abstract void setSysMsgTemplateDao(SysMsgTemplateDao sysMsgTemplateDao);

    /**
     * 注入SysMsgSettingDao和biz中dao注入方法一直
     */
    public abstract void setSysMsgSettingDao(SysMsgSettingDao sysMsgSettingDao);

    /**
     * 注入SysMsgSettingDao
     */
    public abstract void setSysMsgBiz(SysMsgBiz sysMsgBiz);
}
